使用SpringMVC完成多文件上传,以及设置文件类型 您所在的位置:网站首页 上传文件限制文件类型 自定义怎么解除 使用SpringMVC完成多文件上传,以及设置文件类型

使用SpringMVC完成多文件上传,以及设置文件类型

2024-07-16 23:00| 来源: 网络整理| 查看: 265

本文实现的功能: springMvc实现多文件上传,以及使用拦截器对文件类型,文件大小进行拦截. 如果上传的有一个是文件为空,就拦截. 本文运用的知识点: 在文章第4章总结.代码中也有详细的注释

一: 环境准备 1. 导入maven依赖: org.springframework spring-webmvc 5.0.2.RELEASE javax.servlet.jsp javax.servlet.jsp-api 2.3.1 provided javax.servlet javax.servlet-api 3.1.0 provided commons-fileupload commons-fileupload 1.4 2.项目结构

在这里插入图片描述

3. web.xml 配置文件 dispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 dispatcherServlet / CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding UTF-8 forceEncoding true CharacterEncodingFilter /* 4. springmvc.xml配置文件 5. 前端页面(一个请求页面,2个结果页面,结果页面太简单,就是打印一句话,我就不贴出来了) 文件上传(普通方式) 最基本的文件上传 对上传文件的路径和名称进行处理 多文件上传,name属性值必须一样 二:控制器 FileController.java package com.zuoyueer.conntroller; import org.apache.commons.io.FileUtils; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.UUID; /** * @author Zuoyueer * Date: 2019/11/28 * Time: 15:37 * @projectName Framework * @description: 文件控制器 */ @Controller @RequestMapping("file") public class FileController { /** * 同时上传多个文件 */ @RequestMapping("upload3") public String upload3(@RequestParam MultipartFile[] files, HttpServletRequest request) throws IOException { //直接遍历,不需要做非空判断,因为files不可能为空,即使不选择文件也会有其他内容 for (MultipartFile file : files) { String fileName=""; String originalFilename = file.getOriginalFilename(); //getName获取的是表单的name属性值,别用错了 String name = file.getName(); System.out.println(originalFilename+" : "+name); String uuid = UUID.randomUUID().toString().replace("_", "").toUpperCase(); fileName= uuid+"_"+originalFilename; String basePath = request.getServletContext().getRealPath("file3"); String datePath = new SimpleDateFormat("yyy-MM-dd").format(new Date()); File destDir = new File(basePath + "/" + datePath); if(!destDir.exists()){ destDir.mkdirs(); } File destFile = new File(destDir, fileName); file.transferTo(destFile); } return "success"; } /** * 对上传文件的路径和名称进行处理 */ @RequestMapping("upload2") public String upload2(MultipartFile files, HttpServletRequest request) throws IOException { //定义文件名 String fileName = ""; //获取原始的文件名 String originalFilename = files.getOriginalFilename(); //防止文件名重复,设置随机文件名,toUpperCase将字母大写 String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase(); //得到最终的我文件名 fileName = uuid + "_" + originalFilename; //设置存储路径 String basePath = request.getServletContext().getRealPath("files2"); //解决同一个文件夹中文件过多问题,每天一个新的文件夹 String datePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); //创建文件夹 File destDir = new File(basePath + "/" + datePath); if (!destDir.exists()) { destDir.mkdirs(); } //上传文件 File destFile = new File(destDir, fileName); files.transferTo(destFile); //跳转 return "success"; } /** * 最基本的文件上传 */ @RequestMapping("upload") public String upload(MultipartFile files, HttpServletRequest request) throws IOException { //设置保存路径 String path = request.getServletContext().getRealPath("files"); //根据路径创建保存文件夹 File destDir = new File(path); if (!destDir.exists()) { destDir.mkdirs(); } //保存文件 File destFile = new File(destDir, files.getOriginalFilename()); files.transferTo(destFile); //跳转 return "success"; } }

实际上,到这里,就以及能实现,文件的上传了,只不过有一些问题需要解决

文件类型进行限制文件的大小进行限制特别是多文件上传的时候,要实现即使有一个文件为空,就阻止提交.以及不满足以上情况的异常处理 三 .拦截器的实现

文件类型拦截器

package com.zuoyueer.interceptor; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.List; import java.util.Map; import java.util.Set; /** * @author Zuoyueer * Date: 2019/11/28 * Time: 17:54 * @projectName Framework * @description: 上传文件类型拦截器 */ public class FileTypeInterceptor extends HandlerInterceptorAdapter { //允许上传的文件类型 private String suffixList; //set方法的目的是为了,能在配置文件中指定文件类型,实现解耦 public void setSuffixList(String suffixList) { this.suffixList = suffixList; } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean flag = true; //判断是否是文件上传请求 if (request instanceof MultipartHttpServletRequest) { // 转换request,解析出request中的文件 MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request; // 获取文件集合 List files = multipartHttpServletRequest.getFiles("files"); //遍历集合中的文件 for (MultipartFile file : files) { //如果有一个文件为空,就不允许上传 if (file.isEmpty()){ request.setAttribute("errorMessage", "文件为空"); request.getRequestDispatcher("/error.jsp").forward(request, response); //直接拦截,不继续执行下面的其他判断了 return false; } String originalFilename = file.getOriginalFilename(); //对文件类型进行检查,不符合就拦截 if (!checkFile(originalFilename)) { request.setAttribute("errorMessage", "不支持的文件类型"); request.getRequestDispatcher("/error.jsp").forward(request, response); flag = false; } } } return flag; } //检查后缀名是否符合要求 private boolean checkFile(String fileName) { //获取文件后缀(文件类型) String suffix = fileName.substring(fileName.lastIndexOf(".") + 1); if (suffixList.contains(suffix.trim().toLowerCase())) { return true; } return false; } }

文件大小拦截器

package com.zuoyueer.interceptor; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author Zuoyueer * Date: 2019/11/28 * Time: 19:47 * @projectName Framework * @description: 上传文件大小拦截器 */ public class FileSizeInterceptor extends HandlerInterceptorAdapter { private long maxSize; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request!=null && ServletFileUpload.isMultipartContent(request)){ //Servlet请求的上下文信息,都封装在ServletRequestContext对象中 ServletRequestContext servletRequestContext = new ServletRequestContext(request); System.out.println(servletRequestContext.contentLength()); //获取请求内容的大小,包括请求中的全部数据 long contentLength = servletRequestContext.contentLength(); if (contentLength>maxSize){ throw new MaxUploadSizeExceededException(maxSize); } } return true; } public void setMaxSize(long maxSize) { this.maxSize = maxSize; } }

异常处理器

package com.zuoyueer.exception; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @author Zuoyueer * Date: 2019/11/28 * Time: 18:31 * @projectName Framework * @description: 自定义异常处理器 */ public class MyExceptionHandler implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) { ModelAndView modelAndView = new ModelAndView(); //上传文件大小超过限制抛出的异常处理 if (e instanceof MaxUploadSizeExceededException){ modelAndView.addObject("errorMessage", "文件过大"); modelAndView.setViewName("error"); } //其他异常 return modelAndView ; } } 四: 总结 MultipartFile接口

使用之前必须导入文件上传依赖和配置文件上传解析器 MultipartResolver 用于处理文件上传,当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller,在 MultipartResolver 接口中有如下方法:

boolean isMultipart(HttpServletRequest request); // 是否是 multipartMultipartHttpServletRequest resolveMultipart(HttpServletRequest request); // 解析请求void cleanupMultipart(MultipartHttpServletRequest request);

MultipartFile 封装了请求数据中的文件,此时这个文件存储在内存中或临时的磁盘文件中,需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。在 MultipartFile 接口中有如下方法:

String getName(); // 获取参数的名称String getOriginalFilename(); // 获取文件的原名称String getContentType(); // 文件内容的类型boolean isEmpty(); // 文件是否为空long getSize(); // 文件大小byte[] getBytes(); // 将文件内容以字节数组的形式返回InputStream getInputStream(); // 将文件内容以输入流的形式返回void transferTo(File dest); // 将文件内容传输到指定文件中

在文件上传解析器中,还能配置很多属性,其中有一个resolveLazily属性,是懒加载,能够实现文件没有上传(文件过大,网速慢)完也能执行接下来的操作.可惜,没有文件类型的属性,使用,我们必须自定义拦截器来限制文件类型 在这里插入图片描述

MultipartHttpServletRequest

这个接口实际上是对request接口的增强,是文件解析器帮我们完成的封装, 我们直接使用它里面的方法,就能获取到请求中的各种内容. 它的方法有很多,与文件上传相关常用的,就是上面拦截器中使用的那几个~

ServletRequestContext

这个实现类提供对HTTP Servlet的请求所需的请求信息的访问,我之所用这个纯粹是为了用以下而已 实际上是multipartHttpServletRequest.getContentLength()也能获取请求体的大小.

以下博客对我帮助很大,感谢大佬的分享!

https://www.iteye.com/blog/exceptioneye-1314958 https://www.cnblogs.com/tengyunhao/p/7670293.html



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有